
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/timers.h"
#include "freertos/projdefs.h"
#include "factory_time.h"


#define DEV_OK      0

#define DEV_ERR     -1


/**********************************************
* 检查计时器是否到期  
* return 0 - 活动状态　　-1  -  休眠状态 
***********************************************/
int arch_os_timer_is_active(TimerHandle_t timer)
{
	int ret = xTimerIsTimerActive(timer);

	return ret == pdPASS ? DEV_OK : DEV_ERR;
}



/**********************************************
 *　改变定时器到期时间
***********************************************/
int arch_os_timer_change(TimerHandle_t timer, uint32_t ms)
{
	int ret;
	uint32_t ticks = pdMS_TO_TICKS(ms);
	// if (portIsInIsr()) {
    portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
    ret = xTimerChangePeriodFromISR(timer, ticks, &xHigherPriorityTaskWoken);
    portYIELD_FROM_ISR();
	// }
	// else {
	// 	/* Fixme: What should be value of xBlockTime? */
	// 	ret = xTimerChangePeriod(timer, ticks, ARCH_OS_MS2TICK(ARCH_OS_TIMER_OPT_BLOCK_MS_MAX));
	// }

	return ret == pdPASS ? DEV_OK : DEV_ERR;
}

/**********************************************
 *　激活定时器
***********************************************/
int arch_os_timer_activate(TimerHandle_t timer)
{
	int ret;
	// if (portIsInIsr()) {
		portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
		ret = xTimerStartFromISR(timer, &xHigherPriorityTaskWoken);
		portYIELD_FROM_ISR();
	// }
	// else {
	// 	ret = xTimerStart(timer, ARCH_OS_MS2TICK(ARCH_OS_TIMER_OPT_BLOCK_MS_MAX));
	// }

	return ret == pdPASS ? DEV_OK : DEV_ERR;
}



/**********************************************
*  创建定时器
***********************************************/
int arch_os_timer_create(TimerHandle_t* ptimer, const char *name, uint32_t ms,
		    void (*call_back)(TimerHandle_t), void *context,
		    arch_os_timer_reload_t reload,
		    arch_os_timer_activate_t activate)
{
	int auto_reload = (reload == ARCH_OS_TIMER_ONE_SHOT) ? pdFALSE : pdTRUE;
	uint32_t ticks = pdMS_TO_TICKS(ms);

	*ptimer = xTimerCreate((const char * const)name, ticks,
				      auto_reload, context, call_back);
	if (*ptimer == NULL)
		return DEV_ERR;

	if (activate == ARCH_OS_TIMER_AUTO_ACTIVATE){
		if(pdTRUE != xTimerStart(*ptimer, ticks)){
			xTimerDelete(*ptimer, portMAX_DELAY);
			*ptimer = NULL;
			return DEV_ERR;
		}
	}
    return DEV_OK;
}



/**********************************************
*  停用计时器
***********************************************/
int arch_os_timer_deactivate(TimerHandle_t timer)
{
	int ret;
	// if (portIsInIsr()) {
    portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
    ret = xTimerStopFromISR(timer, &xHigherPriorityTaskWoken);
    portYIELD_FROM_ISR();
	// }
	// else {
	// 	ret = xTimerStop(timer, ARCH_OS_MS2TICK(ARCH_OS_TIMER_OPT_BLOCK_MS_MAX));
	// }

	return ret == pdPASS ? DEV_OK : DEV_ERR;
}

void *arch_os_timer_get_context(TimerHandle_t timer)
{
	return (void*)pvTimerGetTimerID(timer);
}


